package scrabble.view;

import java.util.*;

import scrabble.config.Config;
import scrabble.models.Grid.DirectionType;
import scrabble.models.Letter;
import scrabble.models.VirtualPlayer;
import scrabble.simulator.Game;

/**
 * Classe d'interface avec l'utilisateur
 * Gestion des differentes commandes.
 * 
 * @author Hadrien Luttiau
 *
 */
public class Interface {

	public static ArrayList<String> actions = new ArrayList<String>();

	private Game game;
	private ASCIIView board;
	private Scanner sc;
	private boolean affBonus=true;

	public Interface(Game game) {
		System.out.println("Hello and welcome in the Scrabble board game !");
		actions.add("move");
		actions.add("skip");
		actions.add("help");
		actions.add("tb");
		actions.add("lookup");
		actions.add("dist");
		actions.add("scoring");
		actions.add("exchange");
		actions.add("quit");

		this.game = game;
		this.board = new ASCIIView();
		this.sc = new Scanner(System.in);
	}

	public ASCIIView getBoard() {
		return board;
	}

	public boolean isAffBonus() {
		return affBonus;
	}

	public void setAffBonus(boolean affBonus) {
		this.affBonus = affBonus;
	}

	public void menu() {

		String action;
		while (true) 
		{
			if (this.game.getCurrentPlayer() instanceof VirtualPlayer)
			{
				this.game.playVirtualPlayer();
				this.displayView();
				continue;
			}
				
			action = sc.next();
			if(!actions.contains(action))
				System.out.println("Unknown action !");
			else {
				switch(action) {
				case("move") :		// Done
					action_move(sc.nextLine());
				break;

				case("skip") : 		// Done
					this.game.changeCurrentPlayer();
				break;

				case("help") : 		// Done
					action_help();	// RAjouter 
				break;
				case("tb") : 		// Affichage avec/sans bonus
					this.affBonus = !this.affBonus;
				break;
				// End case
				case("lookup") : 	// Done
					action_lookup(sc.next());
				break;
				// End case
				case("dist") : 		// Done
					action_dist();
				break;

				case("scoring") : 	// Done
					action_scoring();	
				break;

				case("exchange") :  // Done
					action_exchange(sc.nextLine());
				break;

				case("quit") : 		// Done
					return;

				} 
				this.displayView();
			}
		}
	}

	private void action_exchange(String s) {
		String inst[] = s.split(" ");
		if (!this.game.exchange_Command(this.game.getCurrentPlayer(), Letter.wordToListOfLetters(inst[1])))
			System.out.println("You don't have the required letters");
	}

	private void action_lookup(String word) {
		if (Game.dictionary.contains(word.toLowerCase()))
			System.out.println("This word exists !");
		else
			System.out.println("This word does not exist !");
	}

	private void action_dist() {
		LinkedHashMap<String, Integer> val = Config.getLetterNumbers();
		Iterator<String> it = val.keySet().iterator();
		Iterator<String> it2 = val.keySet().iterator();

		while(it.hasNext()) {
			String letter = (String) it.next();
			System.out.print(" "+letter + " |");
		}
		System.out.println();
		while(it2.hasNext()) {
			String letter = (String) it2.next();
			int value = val.get(letter);
			if(value >= 10)
				System.out.print(" "+value+"|");
			else
				System.out.print(" "+value+" |");
		}
		System.out.println();
		System.out.println();

	}
	private void action_scoring() {
		LinkedHashMap<String, Integer> val = Config.getLetterValues();
		Iterator<String> it = val.keySet().iterator();
		Iterator<String> it2 = val.keySet().iterator();

		while(it.hasNext()) {
			String letter = (String) it.next();
			System.out.print(" "+letter + " |");
		}
		System.out.println();
		while(it2.hasNext()) {
			String letter = (String) it2.next();
			int value = val.get(letter);
			if(value >= 10)
				System.out.print(" "+value+"|");
			else
				System.out.print(" "+value+" |");
		}
		System.out.println();
		System.out.println();
	}

	private void action_move(String s) {
		String inst[] = s.split(" ");
		DirectionType type = null;
		int row,column;
		String word;

		if (inst.length !=5) {
			System.out.println("Incorrect move synthax ! (move <type> <row> <column> <word>)");
			return;
		}

		if(inst[1].equals("r"))
		{
			type = DirectionType.row;
		}
		else if (inst[1].equals("c"))
		{
			type = DirectionType.column;
		}
		else
		{
			System.out.println("Unknown type ! (r or c)");
			return;
		}
		
		try
		{
			row = Integer.parseInt(inst[2]);
			column = Integer.parseInt(inst[3]);
		}
		catch(Exception e)
		{
			System.out.println("Incorrect move synthax ! (move <type> <row> <column> <word>)");
			return;
		}
		
		word = inst[4];
		
		this.game.move_Command(word.toUpperCase(), row, column, type);
	}

	private void action_help() {
		System.out.println("syntax: [action] <type> <row> <column> <word>");
		System.out.println("action: move, skip, help, defn, tb, lookup, dist, scoring, quit");
		System.out.println();
		System.out.println("skip     = skip turn");
		System.out.println("help     = show this help screen");
		System.out.println("defn     = show list of available definitions");
		System.out.println("tb       = toggle boardmap");
		System.out.println("lookup   = lookup word in dictionary");
		System.out.println("dist     = show letter frequency distribution");
		System.out.println("scoring  = show letter scoring scheme");
		System.out.println("exchange = exchange tiles and sacrifice turn");
		System.out.println("		example: exchange abc");
		System.out.println();
		System.out.println("boardmap scheme:");
		System.out.println("	1 double letter");
		System.out.println("	2 double word");
		System.out.println("	3 triple letter");
		System.out.println("	4 triple word");
		System.out.println();
		System.out.println("type = r or c (row or col)");
		System.out.println();
		System.out.println("press enter to proceed");
		System.out.println();
	}

	public void displayView() {
		this.board.displayView(this.game.getPlayer1(), this.game.getPlayer2(), this.game.getGrid(),isAffBonus());
		this.game.getCurrentPlayer().handview();
	}

	public String askName(String j) {
		System.out.println("Please enter the name of the "+j);
		return sc.nextLine();
	}
}
